{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 感知器算法实验\n",
    "分类器的算法的目的就是求出分类的权向量W。\n",
    "### 感知器算法的基本思想是：\n",
    "- 首先设置一个初始的权向量，然后用已知类别的模式样本去检验权向量的合理性，\n",
    "- 如果检验不合理，就对上一次的权向量进行修正，对修正后的权向量用已知类别的模式样本再去检验其合理性，知道满足合理性的要求为止。\n",
    "- 权值修正的方法一般采用梯度下降法。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 原理\n",
    "设两类线性可分的模式$\\omega_1$, $\\omega_2$，判别函数为$d(X)=W^T*X$,\n",
    "其中$W=[w_1,w_2,...,w_d,w_{d+1}]$ ,$X=[x_1,x_2,...,x_d,x_{d+1}]$,都为增广列矩阵\n",
    "\n",
    "于是对于判别函数$d(X)有$如下性质：\n",
    "\n",
    "对于$\\omega_1$类样本，我们记标签$y=+1, w⋅x_i+b>0$,\n",
    "\n",
    "对于$\\omega_2$类样本，我们记标签$y=-1, w⋅x_i+b<0$,\n",
    "\n",
    "于是$d(X)=sign(w⋅x+b)$\n",
    "\n",
    "我们对样本进行规范化处理，将$d(X)$乘上对应的标签，即可得到判别函数的性质为：$d(X)=W^T*X > 0$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 感知器算法实现步骤：\n",
    "1. 给定初始值:给每个权向量赋任意值\n",
    "\n",
    "2. 输入训练样本进行训练\n",
    "\n",
    "3. 计算判别函数的判别值\n",
    "\n",
    "4. 修改权向量$W(k)$,修正规则如下：\n",
    "\n",
    "  - 若$d(Xi)\\leq0$, 则$W(k+1) = W(k)+ \\rho * y_i * X_i$\n",
    "  - $\\rho$为大于0的一常数(一般取$0<\\rho\\leq1$)\n",
    "  - 否则$W(k+1) = W(k)$\n",
    "\n",
    "5.当W对所有训练样本均稳定不变时，则结束。否则令$k=k+1$,返回步骤2."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 实现Iris数据集分类(两类)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "w= [-0.06500000000000003, 0.14400000000000002]\n",
      "准确率为:100.0%\n"
     ]
    },
    {
     "data": {
      "text/plain": "<Figure size 432x288 with 1 Axes>",
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXgAAAEGCAYAAABvtY4XAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8vihELAAAACXBIWXMAAAsTAAALEwEAmpwYAAAmoElEQVR4nO3deZgdZ3Xn8e/p1mKt3bJbe3erbYwXYUstS7YxOEZg44AhJgkQcOxMzBJNDIlkMJNAFuSQ8TA8mSdBngwkAkLI2KyegXhIQvATIAkJCUh2y1Jsk4CxFu+LurVZS3ef+aPqdt971ct7u6tu1a37+zzPfdS3bnXVW3Xl49I5dd4yd0dERIqnJesBiIhIOhTgRUQKSgFeRKSgFOBFRApKAV5EpKBmZD2Ach0dHd7T05P1MEREGsbOnTufc/fFY32WqwDf09PDjh07sh6GiEjDMLO9432mFI2ISEEpwIuIFJQCvIhIQSnAi4gUlAK8SJOonnZK01AVnwK8SBO4/XZ43/tGg7p79P7227MclaRNAV6k4Nyhvx+2bRsN8u97X/S+v19X8kWWq/vgRSR5ZvBHfxT9vG1b9ALYsiVabpbd2CRdlqf54Dds2OBqdBJJhzu0lP2bfXhYwb0IzGynu28Y6zOlaESaQCktU648J9/silqATjXAm9ljZrbbzPrMTJfmIhkoz7lv2RJduW/ZUpmTb2ZFLkDXIwf/and/rg77EZExmEF7e2XOvZSTb29v7jRNeQEaovNS/j9D98Y+P6nm4M3sMWBDaIBXDl4kPdXBqtGDV1LK/4VT0kgF6Ily8GkH+J8ABwEH/tTdt4+xziZgE0B3d/f6vXvHnRhNRCQVjVyAzrLIeqW7XwK8HnivmV1VvYK7b3f3De6+YfHiMac0FpEGlvcCZhoF6Lwcc6oB3t0fj/98BvgqcFma+xORfMl7ATONAnSejjm1AG9m88xsQeln4FpgT1r7E5F8aYQO2vEK0Fu2TK0AnbdjTi0Hb2bnEF21Q3S3zufd/Y6JfkdFVpFiaZQCZpIF6Hofc2ZF1lopwIsUTyMXMKeqnsesTlaRAstLQW8sReugDTnXeTpmBXiRBpangl61onXQhpzrvB2zZpMUaVB578IsUgdt6LnO2zErBy/SwBqhiFmUDtpaznU9j1lFVpECa8YiZlbyeK5VZBUpqDQKesPDE7+vVZ6LwCVZFU/TPjcK8CINKo2C3saNsH79aFAfHo7eb9w4tTHmuQhcklXxtB7nRgFepEEl3YU5PAwDA9DXNxrk16+P3g8M1H4ln7euzrGEjrFhO17dPTev9evXu4jUZnh44ve1GBpy7+11j0JM9OrtjZZPdWxbtlRub8uW6Y0xabWMMclzndS5AXb4ODFVRVYRqTA0BDPKbqAeHITW1qlvL+nCZC13qISum1XxNIn9qsgqIkG2boVlyyqXLVsWLZ+KpAuTteStQ9fNqvO0Lvsd79I+i5dSNCLZGRx07+iIUgUdHWO/r0V5CqKUeqh+n9b2QtdNeoxpHMtkmCBFo05WEQGiNMzq1fDQQ/Dcc6Npmo6OaHmtaZqkuzrLf3/bttGGo7GajULXzarztF77VQ5eRCqkkYNPsquzlrx16LpJjzFUEvtVDl6kSvV1zXSvc0K3l/R+axHSwOQOt91Wuey228Zv/JnofUl1wJooGE+2vVry1rWsGzrGpKW9XwV4aTpJN5iEbi/Lpp+QBqbSeEKaebI4h7WMr5Z1i0wBXpqKJ9xgErq9pPdbi9AGptBmnqzOYS3NRkk3JjWs8aqvWbx0F43UQ9LNN6Hby7Lpp5YGppBmnqzOYej4prJuo0KNTiKVainUJbm9pPdbi+HhymLp0FDlWGqV1TmUSiqyipSptVA30ftatlfLfpNWSsuUK8/J1yqrcziVcU6271rWazjjXdpn8VKKRtJWS4PJ1q1jN8Vs3Vr79rJqqHGvTM+U0jLV72uR1TmsVci+a1kvr1Cjk0gktMHEPdlHtGX5KLeWFmhrg95e2Lkzer9zZ3QF39ZWe5omq3NYi9B9h67XsMaL/Fm8dAUv9ZJ0ITG0mJdl0a/6Sn2qM0SWZHUOaxlf3ovfSUBFVpGpcRX+pi3Lcxi670b+nlVkFZmCtAp/RRFSmKzlHIZsr9bx5b34nbrxLu2zeClFI3mRZVG0ESRdPE260NkIxe+koCKrSG2yLIrmXdLF0zQKnY1Q/K4H5eBFJlAdXBr+roqElNIapaAMY0/bW1p3snNYy/ZqHWfoE50a9XueKAevAC8iU5J0YbKRC51ZUpFVJGWhBcKQKXvT2neSki5MFrrQmSEFeJFpCp06d+PGyafsTWvfSSpPpyQxFW/S25NRCvAi01BeIJxoqtvQKXvT2HfSkp6KV1P7pkc5eJFpCi0Qlgf1kvLpA9LcdxqSLkw2cqEzSyqyiqQsdCre0Oed1hLsVJxsbiqyiqRo69axp+LduvX09ZYtq1y2bNnp69WSV1dxUiaiAC8yDcPDcO+9Udqltze6Qu/tjd7fe+9obn1oCD7xCXjuOejoiK7cOzqi95/4RPQ51JZXV3FSJqNOVpFpaGmB66+Pfu7rG0239PZGy0upk9ZWWL0aHnooCuqlNE1HR7S89HvlnZTbto3m1sfKqxe9C1OmTzl4kQSkkYMPzaurONnclIMXmaKQxiR3eP/7K5e9//1jNyDddlvlsttuG3u9W2+tXHbrreOnXKqD+UT/I5jofa3rSf6lHuDNrNXMHjCzr6e9L5EkhTQmhebBa1nviivgzjth8+Zovc2bo/dXXDH1YBtauM2icUrSU48r+C3Aw3XYj0hiQhuTQpt0smzmCS3cZtU4JSkabx7hJF5AJ/B3wGuAr0+2vuaDlzwpfzh16TXeQ6qTfGTf8LD75s2V+928eXpzkzfL4+uaEVk9ss/M7gE+CiwAPuDubxxjnU3AJoDu7u71e/fuTW08IrUKLZ4mLY3mpdBtqnGqsWRSZDWzNwLPuPvOidZz9+3uvsHdNyxevDit4UiDy6LwV0rLlCvPyU80numMr9Yia+g2m/7xdc1ovEv76b6IrtwPAI8BTwHHgLsm+h2laGQsST/OLUR5eqaUlql+n8b4hofdL7+8Mi1TStdcfvnUUiXN9Pi6ZsQEKZrUruDd/UPu3unuPcDbgW+5+01p7U+KKavCX0sLtLVVTga2c2f0vq1tNIXRCIXJRigES0rGi/xJvoCNqMgqU5Rl4a+6oDpegTXJ8aVRZC1td6L3ta4n+UBWRdZaqZNVxpP3wl/S48v78Up+qJNVGlqWhb+Q4mnS41OhU5KiAC+5Vp7TrveMiSFdnUmPL8vjleLRbJKSa1nNmFhePIVon+WB1z3ad9Lj0wyRkqRJc/BmZsCNwDnu/hEz6waWufv3kx6McvAynlJAHe99WvsMfRxe0uPL4nilMU3rkX1m9klgGHiNu19oZouAb7r7pUkPVAFe8kbFTsm76RZZL3f39wLHAdz9IDArwfGJ5JKn0FEqUk8hAf6UmbUCDmBmi4mu6EUKyz2daXtF6ikkwN8JfBVYamZ3AN8F/luqoxIRkWkLanQyswuAq+O333L3VOZ3Vw5e8qSUornzztFlmzfDxz+uPLzkRxKNTnOB1nj9OUkNTCTPzKJgXk7BXRrJpAHezD4MfA44E+gAPmtmv5P2wESyVktHaUjHq0i9hVzB3whc6u63u/tW4OXAL6U7LJFs1dJRqueYSl6FdLI+AZxBfJskMBt4PLURieRAaEdpaMerSBZCGp2+BlwK3Ed0q+Rrge8TPcwDd9+c1GBUZJW8CekoraXjVSRp0+1k/eWJPnf3z01jbBUU4IuhGdvsQztem/HcSLomCvCTpmiSDOBSfLffHqUsSlevpavb9vbi5qTHK8ZWX8E347mRbIXcRfNSM7vHzB4ys0dLr3oMThpLIzy+LmmhxdhmPDeSvZAi62eBrcAfAa8G3oHmkZcxlBcit20bzUkXOR8dWoxtxnMj2QvJwe909/VmttvdLy5flvRglIMvhmacgTE0t96M50bSNd1O1hNm1gL8h5n9mpn9HDA/0RFKYTTr4+aqg/R4wb0Zz41kJyTAbyGaqmAzsB64CZjwzhppTnrc3Ph0biQLIXfR/CD+8QhR/l1kTHrc3Ph0biQLITn4+4C3unt//H4R8EV3/+mkB6McfDHoXu/x6dxI0qabg+8oBXcYeaLTkoTGJgUUko9uVjo3Uk8hAX44ftA2AGa2ivjpTtJcQmdM1MyKIvkQch/8bwPfNbO/Bwz4KWBTqqOS3AntwlS3pkh+THoF7+7fAC4BvgR8EVjv7n+b9sAkP0K7MNWtKZIvIUXWVwJ97n7UzG4iCvbb3H1v0oNRkTW/QmdM1MyKImGeGjhO3/6DPLC/n0MvDvLRn794StuZ7mySDwJrgTVE0xZ8BvgFd3/VlEYzAQX4fKtlxkR1a4qMOnpikAcPDNC3v5++/Qfp29/P04dOADCrtYW1XW18adMVtLTU/h/KtGaTBAbd3c3sTcD/cvfPmNm7ah6FNLTQGRND1xMpqqFh5z+eOUzfvv44oPfz708fZji+lu45ay4vP+cserva6e1qZ/WKhcye0ZrKWEIC/GEz+xBRB+tV8bQFM1MZjeRSdRdm+VOL4PSC6mTriRRJeaqlb18/ux8f4NjJIQDa5sykt6udn37ZMnq72+ntbGfRvFl1G1tIgH8b8IvAu9z9qfiWyT9Id1iSJ7XMmKhuTSmyoycG2f14nGqJr9CfOhQ9zXRmq7F6+ULeur4zCuZdi+g5ay6W4V/8SXPw9aQcfL7VMmOiujWl0U2Wauk+c+5ImqW3u53Vyxdyxsx0Ui0TmW4OXgQI78JUt6Y0oqcPHeeBkWB+kN0HBjhalmpZ29XOtS9bxrqudtZ2tXNmHVMtU6UALyJN59jJ0btadsVX508OjKZaLly+kDev7xy5Qj+7Y16mqZapGjfAm9nfufvVZvYxd//Neg5KRCQpQ8POj545MnJ74gP7KlMtXWfOYUPPmSPB/GUrskm1pGGiK/jlZvYK4Hoz+yLRNAUj3P3+VEcmIjIFTx86PpIz79vXz4MH+kdSLQvPmMHarnZeu3opvXGqpWP+7IxHnJ6JAvyHgd8FOoE/rPrMgdekNSgRkRDHTg6ye6SBqDLVMqMlSrX8/CWdI4XQs8+aN6VmokY1boB393uAe8zsd9399+s4JmkSuttGajE07Pz42SP07euP7jmP72oZinMtXWfOYf2qRfR2tbOuu52XrWgrTKplqkKe6PT7ZnY9cFW86Dvu/vXJfs/MzgD+AZgd7+ced986ncFKcWjWSZnMM4eOjwTyUgPRkRODACw4Ywa9Xe1cc+FLmiLVMlWTBngz+yhwGXB3vGiLmb3C3X9rkl89AbzG3Y+Y2UyiKYf/xt3/ZXpDlkZXPuskVHa8btmiK/lm9OLJobiB6OBIQH+iLNVywfIF/Oy6FfR2RVfo53Q0V6plqkJuk3wD0OvuwwBm9jngAWDCAO9RB9WR+O3M+JWfrirJTHmH67Zto4Fes042h+E41VJ+df7DslRL56I5XLJqEe+M72q5aKVSLVMVOpvkRnd/IX5/JlGaZs2kGzdrBXYC5xJNVHba7ZZmton4ASLd3d3r9+5NfBZiySnNOtkcnjl8vKIb9MEDZamW2dFdLaVbFNd2tbN4gVIttZhuJ+tHgQfM7NtEt0peBXwwZMfuPgT0mlk78FUzu8jd91Stsx3YDtFUBSHblcanWSeL6cWTQ+x5YqAioD/e/yIArS3GBcsW8KbeFSOF0HM65ivVkqKQIusXzOw7wKXxot9096dq2Ym798f/g3gdsGey9aXYNOtkMQwPO48+d6Ssvb+fR54aTbWsbJ9Db3c773hlT9xA1MacWUq11FPQVAXu/iRwby0bNrPFwKk4uM8BXgt8rPYhStFo1snG9OzhEyPztOzaP8CuA/0cPj6aalnT1cavvuqckUKoUi3ZS202STNbA3wOaCV69uuX3f0jE/2OZpNsLroPPr+OnxpiTzwtbmme8+pUS29Z7vwli5VqyUoms0m6+4PAurS2L41Ps07mQ5RqOVrxOLlHnjzMYHmqpaudm1/RQ293Oxcp1dIwggJ8fDfM0vL13X1fWoMSkfQ8f+RERWt/3/7RVMv82TNY29XGpqvOGWnvX7LgjIxHLFMV0uj068BW4GlgOF7sRA/hFpEcO35qiH97YoAH9vWz60DUSLT/hdFUy/lLF/Aza+O7WpRqKZyQK/gtwPnu/nzagxGRqRsedn7y/NGKWxQffvLQSKplRdsZ9Ha380svX0Vv1yIuWrmQubP0SIgiC/l29wMDaQ9ERGpTSrXsiguhu/b3c6gs1bKmsyzV0tXOkoVKtTSbiR748f74x0eB75jZXxHNLwOAu1dPISwiKYlSLYfK8uajqZYWg/OXLeQNa1awLs6bv2TxfFqVaml6E13BL4j/3Be/ZsUv0JwyIqkppVp27a9MtZwaOj3VsraznYs725RqkTFNNB/87wGY2Vvd/Svln5nZW9MemEizeOHoyej2xH2np1rmzWplTWc77/6pc0YKoUq1SKiQ/+1/CPhKwDIRmcTxU0M89OShikLovheOAVGq5bylC3jDmuVx3nwR5y5RqkWmbqIc/OuB64CVZnZn2UcLgcG0BybS6Nydn4w0EEVX5g+VpVqWt51Bb1c7N17eTW+XUi2SvIn+Nj0B7ACuJ5ryt+Qw8L4xf0Okib1w9OTIHS2lgD7w4ikgSrVc3NnGu648Z2QmxaVKtUjKJsrB7wJ2mdnn3f1UHcckknsnBuO7Wvb1s+tAFND3Pl+Zarnu4mUjc5y/dMkCpVqk7kL+PXi/mVXfNTNAdHX/X9UAJUXn7jz2/LGRQmhfVapl2cIo1XLDZXGqZWUb82Yr1SLZC/lb+DfAEPD5+P3bgbnAU8CfAz+TyshEMnLw6En6DvSPBPNdB/rpPxb9I3burFbWdLbxzivPju4571rEsjalWiSfQgL8Ne5+Sdn73WZ2v7tfYmY3pTUwkXo4MTjEQ2UNRLv29/NYVarldS9bNjLxllIt0khCAnyrmV3m7t8HMLNLieZ4B91NIw3E3dn7/LGRYP7A/n4efuIQJ4eiOfSWLpxNb1c7b7s0SrWs6VSqRRpbyN/edwN/ZmbziZ7Jegh4t5nNI3peq0guHTx6cqQAWro6P1iWarl4ZRvvuLJHqRYprJBnsv4AuNjM2uL35ROPfTmtgYnU4sTgEA8/eZi+fQdHAnop1WIG5y1ZwLWrl9HbHU289dIl85nR2pLxqEXSFTIf/GzgzUAPMMPix+5M9vg9kbS4O/teiFItpQc+PzRGquUXLu2KUy3tzFeqRZpQyN/6vyS6LXInZbNJitRL/7GTFU8fKk+1zJkZNRC945U9I4XQ5W1zMh6xSD6EBPhOd39d6iMRAU4ODvPwk4cqAvpPnjsKRKmWly6Zz2tXL6W3axG9Xe2ct1SpFpHxhAT4fzazi919d+qjkaZSnWrZdaCff3viECcHo1TLkgVRquWtGzqVahGZgpD/Wq4EbjaznxClaAxwd9czWaUmA8dOlTUQHWTXgQFeOHoSiFMtK9u4+RU9I08gWt52BqWaj4jULiTAvz71UUjhnBwc5pGn4lRLXAh9tCrVcs2FS+jtWsTarjbOX7pAqRaRhIXcJrnXzK4EXurunzWzxcD89IcmjcLd2f/Cizywf/QWxfJUy+I41fLm9Z2si6fFXXDGzIxHLVJ8IbdJbgU2AOcDnwVmAncBr0x3aJJXA8dOndZA9HycajljZgsXr2zjl69YFRVCu9tZoVSLSCZCUjQ/B6wD7gdw9yfMbMHEvyJFMVmq5dzF83nNBUtGGojOW7qAmUq1iORCSIA/6e5emjI4nqJACsjdOXDwxeiBFXEhdE9ZqqVj/miqpfQEooVKtYjkVkiA/7KZ/SnQbma/ArwT+FS6w5J6GHjxFLviFEsp3aJUi0hxhBRZ/4eZvZZokrHzgQ+7+32pj0wSdWpomEeePEzf/oMjj5R79NnRVMtLFs/n1RcsGblF8fxlSrWINLqgrpE4oCuoN4hSqqW8G3TP4wOcqE61XNLJ2s521nQp1SJSROMGeDM7DFQ/qg9GG50WpjYqqcnAi6d4MG4gKt3d8tyRKNUye0aUavmll68aKYSubJ+jVItIE5joodu6UyaHTg0N88OnDlcUQn8cp1oAXrJ4Hq86L7qrZZ1SLSJNTRN75Fh1qmXX/n52V6RaZtHb1c7PrVtJb9cipVpEpIICfI4cOn6KB/cP0DfSETrAc0eiGZpnz2jhopVt3PTyVSOF0M5FSrWIyPgU4DNSSrWUF0J//OwRPK56RKmWxVHevLOdC5Yr1SIitVGArwN35/H+Fyu6Qfc8McDxU1Gq5ax5UarlTWtX0NsdTYvbNkepFhGZHgX4FBw6fordBwYqHilXSrXMmtHCRSsW8ouXrRophCrVIiJpUICfpsGhYR6ZINVyzuJ5XHVeB+u62untWsT5yxYwa4ZSLSKSPgX4Grg7TwwcH7k9sS++q6WUajkzTrVcv3YFvV3trO1sp22uUi0ikg0F+AkcPn6KB+NUS+n17OHKVMsNl3XT29XOuq5FdJ2pVIuI5EdqAd7MuoC/AJYSdcRud/dtae1vugaHhvnh04crCqE/Kk+1dMzjp87tGOkGvWDZQqVaRCTX0ryCHwRuc/f74/njd5rZfe7+UIr7DFKeatkVt/jvfnyAF08NAbBo7kx6u9p545rorpa1nW20z52V8ahFRGqTWoB39yeBJ+OfD5vZw8BKoO4B/siJQR7c3z8yi2JFqqW1hdUrFvK2S7tYF1+dd585V6kWEWl4dcnBm1kP0VOh/nWMzzYBmwC6u7unva/BoWH+/ekjcSCPCqH/8cxoquXsjnlceW7HSDfohcuVahGRYko9wJvZfOD/ALe6+6Hqz919O7AdYMOGDWPNXjmhU0PD3PfQ0yO58/JUS3ucarnu4uUjAV2pFhFpFqkGeDObSRTc73b3/5vGPlrM+I17HuTk4DAXxqmWUjBfdZZSLUHuvht++7dh3z7o7oY77oAbbyzufkWaRJp30RjwGeBhd//DtPbT2mJ87b2voOvMucye0ZrWborr7rth0yY4dix6v3dv9B7SDbZZ7VekiZh7zVmRsA2bXQn8I7AbGI4X/5a7//V4v7NhwwbfsWNHKuORcfT0RMG12qpV8NhjxduvSMGY2U533zDWZ2neRfNdoqc/SZ7t21fb8kbfr0gT0e0jzW68O5cSuKMpl/sVaSIK8M3ujjtg7tzKZXPnRsuLuF+RJqIA3+xuvBG2b49y32bRn9u3p1/ozGq/Ik0ktSLrVKjIKiJSm4mKrLqCFxEpKAV4yc7dd0e3S7a0RH/efXf99v2e98CMGVF6aMaM6H09ZHnM0nQ0H7xkI8tGp/e8Bz75ydH3Q0Oj7z/xifT2q+YuqTPl4CUbWTY6zZgRBfVqra0wOJjeftXcJSlQDl7yJ8tGp7GC+0TLk6LmLqkzBXjJRpaNTq3jzFk03vKkqLlL6kwBvshCC3pJFxyvuSbaVul1zTWnr3PHHTCz6oHkM2fWp9GplPcOXZ4UNXdJvbl7bl7r1693Schdd7nPnesOo6+5c6Pl5W65pXKd0uuWW6a236uvHnt7V199+vhmzapcZ9as08eXlltucW9tjfbb2jr1463VXXe5r1rlbhb9Wa/jlcICdvg4MVVF1qIKLeglXXCcaP798r9rKjiKJEJF1mYUWtBTwVGksBTgiyq0oKeCo0hhKcA3opDiaWhBr5aCY0jx9Oqrx95e9fI77ojGX66lZfyCY2ghOKvCcih1sko9jZecz+KlImuA0OJpad2Qgl5IwbGW4ulY61XvO3R7pfGFFIKzKiyHquW7EwmEiqwFklVxMuniaej2ILwQnFVhOZQKy5KCiYqsCvCNpqXl9AAIUcAcHj59eVJCA3Lo+GoJ8FnuO0lZfXdSaLqLpkjyXpxMY3yhhWAVlkUqKMCnLemiWq3FyRAhBcdaiqezZlUumzXr9PGFbg/CC8FpFJaT/P7UySr1Nl5yPotX4YqsaRTVki4Q1lLADCme3nWX+8yZlevMnDm9Quddd40WgUuv1tb0C8tpfH/qZJWEoSJrRtIoqiVdIEy6gJlGoTOr4qSKotIAVGTNShpFtaQLhEkXMNModGZVnFRRVBqAiqxZqbWoFpLvraVAmOT2Qo8ljUJnGsXJkHOjoqg0OAX4NJ17bvjy0uPc9u6NrhpLj3OrDjyhBcKktxdaILzuurG3V728lkJn0sXJ0HMTeiwieTVecj6LV+GKrNWFwfICYbVVq8Zed9Wq09cNKRAmvT33sAJhGvsN3Xeo0DHWciwiGUFF1oxkmWdW3np8SdcTRDKkHHxWsswzZ5U/boS8ddL1BJGcUoBPU5Z55qyaakIbnbIUem6ybEzSrJOShPFyN1m8CpeDd88uz5zG9kL3GdLolLXQc5PVOdSskxII5eClbtQcNH06h1ID5eClfvQovunTOZSEKMBLslSYnD6dQ0mIAvxUqQg2Ns2YOH06h5IQBfipCO2EbEY33gjbt0f5YrPoz+3bo+USRudQEqIi61SoCCYiOaEia9JUBBORBqAAPxUqgolIA0gtwJvZn5nZM2a2J619ZCbrIpgKvCISIM0r+D8HXpfi9rOTZRFMBV4RCZRqkdXMeoCvu/tFIes3TJE1SyrwikiZXBdZzWyTme0wsx3PPvts1sPJPxV4RSRQ5gHe3be7+wZ337B48eKsh5N/KvCKSKDMA7zUKOsCr4g0DAX4RqMuRxEJNCOtDZvZF4CNQIeZHQC2uvtn0tpfU7nxRgV0EZlUagHe3W9Ia9siIjI5pWhERApKAV5EpKAU4EVECkoBXkSkoHI1H7yZPQuM0YcfpAN4LsHhZKkox1KU4wAdSx4V5Thgeseyyt3H7BLNVYCfDjPbMd58DI2mKMdSlOMAHUseFeU4IL1jUYpGRKSgFOBFRAqqSAF+e9YDSFBRjqUoxwE6ljwqynFASsdSmBy8iIhUKtIVvIiIlFGAFxEpqIYL8GbWamYPmNnXx/hstpl9ycx+ZGb/Gj8yMLcmOZabzexZM+uLX+/OYowhzOwxM9sdj/O0Zy5a5M74e3nQzC7JYpwhAo5lo5kNlH0vH85inCHMrN3M7jGzR8zsYTO7ourzhvheAo6jIb4TMzu/bIx9ZnbIzG6tWifR7yS12SRTtAV4GFg4xmfvAg66+7lm9nbgY8Db6jm4Gk10LABfcvdfq+N4puPV7j5eo8brgZfGr8uBT8Z/5tVExwLwj+7+xrqNZuq2Ad9w97eY2Syg6kkxDfO9THYc0ADfibv/EOiF6OIOeBz4atVqiX4nDXUFb2adwBuAT4+zypuAz8U/3wNcbWZWj7HVKuBYiuRNwF945F+AdjNbnvWgiszM2oCrgM8AuPtJd++vWi3330vgcTSiq4Efu3t1536i30lDBXjg48BvAMPjfL4S2A/g7oPAAHBWXUZWu48z8bEAvDn+Z9o9ZtZVn2FNiQPfNLOdZrZpjM9HvpfYgXhZHk12LABXmNkuM/sbM3tZPQdXg7OBZ4HPxmnAT5vZvKp1GuF7CTkOaIzvpNzbgS+MsTzR76RhAryZvRF4xt13Zj2W6Qo8lv8H9Lj7GuA+Rv9lkkdXuvslRP+8fK+ZXZX1gKZhsmO5n2juj7XA/wS+VufxhZoBXAJ80t3XAUeBD2Y7pCkJOY5G+U4AiNNM1wNfSXtfDRPggVcC15vZY8AXgdeY2V1V6zwOdAGY2QygDXi+noMMNOmxuPvz7n4ifvtpYH19hxjO3R+P/3yGKKd4WdUqI99LrDNeljuTHYu7H3L3I/HPfw3MNLOOug90cgeAA+7+r/H7e4gCZblG+F4mPY4G+k5KXg/c7+5Pj/FZot9JwwR4d/+Qu3e6ew/RP2++5e43Va12L/DL8c9vidfJXSdXyLFU5d2uJyrG5o6ZzTOzBaWfgWuBPVWr3Qv8p/gOgZcDA+7+ZJ2HOqmQYzGzZaW6jpldRvTfUO4uItz9KWC/mZ0fL7oaeKhqtdx/LyHH0SjfSZkbGDs9Awl/J414F00FM/sIsMPd7yUqxPxvM/sR8AJR8GwYVcey2cyuBwaJjuXmLMc2gaXAV+P/vmYAn3f3b5jZrwK4+58Afw1cB/wIOAa8I6OxTibkWN4C3GJmg8CLwNvzeBER+3Xg7jgl8Cjwjgb9XiY7job5TuILh9cC/7lsWWrfiaYqEBEpqIZJ0YiISG0U4EVECkoBXkSkoBTgRUQKSgFeRKSgFOAll8zsSArb7DWz68re325mH5jG9t4az2747QTGdquZjTWJVvV63zGzQjxoWtKnAC/NpJfoHuOkvAv4FXd/dQLbupWxZ0kUmTIFeMk9M/svZvaDeOK134uX9cRXz58ys38zs2+a2Zz4s0vjdfvM7A/MbE/cJPMR4G3x8tI00qvjq+JHzWzzOPu/waI54veY2cfiZR8GrgQ+Y2Z/ULX+RjP7BzP7KzP7oZn9iZm1xJ9da2bfM7P7zewrZjY/3u8K4Nulfw2Y2SfNbEd8bL+X+EmV5uDueumVuxdwJP7zWqIHEhvRBcnXiaaP7SHq8u2N1/sycFP88x7givjn/w7siX++Gfjjsn3cDvwzMBvoIGpvn1k1jhXAPmAxUXfrt4CfjT/7DrBhjLFvBI4D5wCtRJPFvSXexz8A8+L1fhP4cPzzY0BH2TbOjP9sjfezZqJ96qXXWK+Gn6pACu/a+PVA/H4+0cMQ9gE/cfe+ePlOoMfM2oEF7v69ePnngYkeBPFXHk3qdsLMniGaruBA2eeXAt9x92cBzOxuov/BfG2ScX/f3R+Nf+cLRFf7x4HVwD/F0yHMAr43zu//gkXTFc8Alse/9+Ak+xSpoAAveWfAR939TysWRo9jPFG2aAiYM4XtV28jqf8mqucAcaJjuc/db5joF83sbOADwKXuftDM/hw4I6FxSRNRDl7y7m+Bd5rZfAAzW2lmS8Zb2aOn/Rw2s9JjzsonnDsMLKhx/98HXmVmHRY9Zu0G4O8Dfu8yMzs7zr2/Dfgu8C/AK83s3PhY5pnZeWOMbSHRvOcDZraUaHpZkZrpCl5yzd2/aWYXAt+L0xpHgJuIrrbH8y7gU2Y2TBSMB+Ll3wY+aGZ9wEcD9/+kmX0w/l0jSun8ZcCv/gD4Y+Dc+He/6u7DZnYz8AUzmx2v9zvAvxPVGb5hZk+4+6vN7AHgEaKn+/xTyFhFqmk2SSkcM5vv8QMg4uC83N231HH/G4EPeM4fAi3Fpyt4KaI3mNmHiP5+7yW/c+mLpEpX8CIiBaUiq4hIQSnAi4gUlAK8iEhBKcCLiBSUAryISEH9f1dylIYi37xrAAAAAElFTkSuQmCC\n"
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "\"\"\"实现Iris的分类\"\"\"\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "path = 'Iris.data'\n",
    "df = pd.read_csv(path,header=None)\n",
    "x = df.loc[:99,[0,2]].values   #第一列和第三列的数据\n",
    "y = df.loc[:99,4].values\n",
    "y = np.where(y == 'Iris-setosa',-1,1)\n",
    "x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2,random_state=200)\n",
    "\n",
    "def perceptron(Train_data, Label, exercise_times=50):\n",
    "    '''\n",
    "    训练感知器模型\n",
    "    :param Train_data:训练用的样本\n",
    "    :param Label:样本对应的标注\n",
    "    :param exercise_times:迭代次数\n",
    "    :return: W, b参数向量\n",
    "    '''\n",
    "    # 将数据转换成矩阵形式（在机器学习中因为通常都是向量的运算，转换成矩阵形式方便运算）\n",
    "    # 转换后的数据中每一个样本的向量都是横向的\n",
    "    dataMat = np.mat(Train_data)\n",
    "\n",
    "    # 将标签转换成矩阵，之后转置(.T为转置)。\n",
    "    # 转置是因为在运算中需要单独取label中的某一个元素，如果是1xN的矩阵的话，无法用label[i]的方式读取\n",
    "    # 对于只有1xN的label可以不转换成矩阵，直接label[i]即可，这里转换是为了格式上的统一\n",
    "    labelMat = np.mat(Label).T\n",
    "\n",
    "    # 获取数据矩阵的大小，为m*n\n",
    "    m, n = np.shape(dataMat)\n",
    "    # 创建初始权重w，b\n",
    "    w = np.zeros((1, np.shape(dataMat)[1]))\n",
    "    # 1代表一行，np.shape(datamat)[1]输出的是列数，也就是说W是一行，n列的矩阵\n",
    "    b = 0\n",
    "    # 初始学习率\n",
    "    learning_rate = 0.01\n",
    "\n",
    "    for k in range(exercise_times):\n",
    "        # 对于每一个样本进行梯度下降\n",
    "        for i in range(m):\n",
    "            # 获取当前样本的向量\n",
    "            xi = dataMat[i]\n",
    "            yi = labelMat[i]\n",
    "            if -1*yi * (w * xi.T + b) >= 0:\n",
    "                w = w + learning_rate * yi * xi\n",
    "                b = b + learning_rate * yi\n",
    "    return w.tolist(), b.tolist()\n",
    "\n",
    "\n",
    "def test(dataArr, labelArr, w, b):\n",
    "    '''\n",
    "    分类器的测试\n",
    "    :param dataArr: 样本的特征集\n",
    "    :param labelArr: 样本的标注\n",
    "    :param w: 权重向量\n",
    "    :param b: 偏置向量\n",
    "    :return: 准确率\n",
    "    '''\n",
    "    dataMat = np.mat(dataArr)\n",
    "    labelMat = np.mat(labelArr).T\n",
    "    m, n = np.shape(dataMat)\n",
    "    # 错误样本数计数\n",
    "    errorCnt = 0\n",
    "    # 遍历所有测试样本\n",
    "    for i in range(m):\n",
    "        xi = dataMat[i]\n",
    "        yi = labelMat[i]\n",
    "        # 获得运算结果\n",
    "        result = -1 * yi * (w * xi.T + b)\n",
    "        # 如果-yi(w*xi+b)>=0，说明该样本被误分类，错误样本数加一\n",
    "        if result >= 0: \n",
    "            errorCnt += 1\n",
    "    acc = 1 - (errorCnt / m)\n",
    "    return acc\n",
    "\n",
    "W,B = perceptron(x_train, y_train, exercise_times=2000)\n",
    "w = W[0]\n",
    "b = B[0]\n",
    "x_x = np.linspace(4,7,10)\n",
    "y_y = -(w[0] * x_x + b[0])/w[1]\n",
    "print(f\"w= {w}\")\n",
    "test_acc = test(x_test, y_test, W, B)\n",
    "print(f\"准确率为:{test_acc*100}%\")\n",
    "plt.plot(x_x,y_y)\n",
    "plt.scatter(x[0:49,0],x[0:49,1],color='red',marker='o',label='-1')\n",
    "plt.scatter(x[50:100,0],x[50:100,1],color='blue',marker='x',label='1')\n",
    "plt.xlabel('length of petal')\n",
    "plt.ylabel('length of scape')\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}